//enum 解构
enum Direction {
    East,
    West,
    North,
    South,
}

fn test_match_deconstruct_enum() {
    let direction = Direction::North;

    match direction {
        Direction::East => println!("East"),
        Direction::South | Direction::North => { //多重匹配
            println!("South and North");
        },
        _=>println!("West"),
    };
}

//tuple解构
enum Action {
    Say(String),
    MoveTo(i32, i32),
    ChangeColorRGB(u16, u16, u16),
}

fn test_match_deconstruct_tuple() {
    let action = Action::ChangeColorRGB(255,244,133);

    match action {
        Action::Say(s) => {
            println!("{}", s);
        },
        Action::MoveTo(a,b) => {
            println!("pointer from (0,0) move to ({},{})", a, b);
        },
        Action::ChangeColorRGB(x,y,z) => {
            println!("change color to ({},{},{})", x, y , z);
        },
    };
}

//struct解构
fn test_match_deconstruct_struct() {
    struct Point {
        x : i64,
        y : i64,
    }

    let point = Point{x:0, y :0};

    match point {
        Point{x,y} => { println!("struct = ({},{})",x,y)},
    };
}

//在模式匹配中，当我想要匹配一个数字(字符)范围的时候，我们可以用...来表示
fn test_match_range() {
    let x = 1;
    match x {
        1 | 2 => println!("1 or 2"),
        3 ... 10 => println!("1~10"),
        _=>println!("other"),
    };
}

//防止未实现Copy的类型会被默认的move掉，怎么做呢？答：用ref或者ref mut
fn test_match_ref_mut() {
    let mut x = 5;
    match x {
        ref mut mr => println!("ref mut : {}", mr),
    }
}

//后置条件：以倒序的方式判断每一个条件是否成立
fn test_match_guards() {
    let x = 4;
    let y = false;

    match x {
        4 | 5 if y => println!("yes"),
        _ => println!("no"),
    };
}

fn main() {
    test_match_deconstruct_enum();
    test_match_deconstruct_tuple();
    test_match_deconstruct_struct();
    test_match_range();
    test_match_guards();
}
